﻿using System.Drawing;

namespace Tetris {
    // ██
    //   ██
    class Block5: Block {
        /**
         * 构造方法。
         */
        public Block5() {
            mBlocks[1, 0].mUsed = mBlocks[1, 1].mUsed = mBlocks[2, 1].mUsed = mBlocks[2, 2].mUsed = true;
        }

        /**
         * 擦除。
         */
        protected override void Erase() {
            Rectangle rect;

            switch (mShape) {
                case Shape.ONE:
                    rect = new Rectangle(Const.GRID_SIZE * mLine, Const.GRID_SIZE * (mRow + 1), Const.GRID_SIZE * 2, Const.GRID_SIZE);
                    base.EraseRect(rect);
                    rect = new Rectangle(Const.GRID_SIZE * (mLine + 1), Const.GRID_SIZE * (mRow + 2), Const.GRID_SIZE * 2, Const.GRID_SIZE);
                    base.EraseRect(rect);
                    break;
                case Shape.TWO:
                    rect = new Rectangle(Const.GRID_SIZE * mLine, Const.GRID_SIZE * (mRow + 1), Const.GRID_SIZE, Const.GRID_SIZE * 2);
                    base.EraseRect(rect);
                    rect = new Rectangle(Const.GRID_SIZE * (mLine + 1), Const.GRID_SIZE * mRow, Const.GRID_SIZE, Const.GRID_SIZE * 2);
                    base.EraseRect(rect);
                    break;
            }
        }

        /**
         * 获取底端所在的行数。底端是指方块最下方的有效格。
         * @return 底端所在的行数
         */
        public override int GetBottom() {
            return mRow + 2;
        }

        /**
         * 获取顶端所在的行数。顶端是指方块最上方的有效格。
         * @return 顶端所在的行数
         */
        public override int GetTop() {
            if (mShape == Shape.ONE) {
                return mRow + 1;
            }
            return mRow;
        }

        /**
         * 对不能下落的处理。
         */
        protected override void HandleCannotMoveDown() {
            switch (mShape) {
                case Shape.ONE:
                    Game.sExistentBlocks[mRow + 1, mLine].mUsed = 
                    Game.sExistentBlocks[mRow + 1, mLine + 1].mUsed = 
                    Game.sExistentBlocks[mRow + 2, mLine + 1].mUsed = 
                    Game.sExistentBlocks[mRow + 2, mLine + 2].mUsed = true;
                    Game.sExistentBlocks[mRow + 1, mLine].mColor =
                    Game.sExistentBlocks[mRow + 1, mLine + 1].mColor =
                    Game.sExistentBlocks[mRow + 2, mLine + 1].mColor =
                    Game.sExistentBlocks[mRow + 2, mLine + 2].mColor = mColor;
                    break;
                case Shape.TWO:
                    Game.sExistentBlocks[mRow + 1, mLine].mUsed = 
                    Game.sExistentBlocks[mRow + 2, mLine].mUsed = 
                    Game.sExistentBlocks[mRow, mLine + 1].mUsed = 
                    Game.sExistentBlocks[mRow + 1, mLine + 1].mUsed = true;
                    Game.sExistentBlocks[mRow + 1, mLine].mColor =
                    Game.sExistentBlocks[mRow + 2, mLine].mColor =
                    Game.sExistentBlocks[mRow, mLine + 1].mColor =
                    Game.sExistentBlocks[mRow + 1, mLine + 1].mColor = mColor;
                    break;
            }
        }

        /**
         * 下落。
         * @return 成功则返回 true，否则返回 false
         */
        public override bool MoveDown() {
            switch (mShape) {
                case Shape.ONE:
                    if (mRow == 17) {
                        this.HandleCannotMoveDown();
                        return false;
                    }
                    if (Game.sExistentBlocks[mRow + 2, mLine].mUsed || 
                        Game.sExistentBlocks[mRow + 3, mLine + 1].mUsed || 
                        Game.sExistentBlocks[mRow + 3, mLine + 2].mUsed) {
                        this.HandleCannotMoveDown();
                        return false;
                    }
                    break;
                case Shape.TWO:
                    if (mRow == 17) {
                        this.HandleCannotMoveDown();
                        return false;
                    }
                    if (Game.sExistentBlocks[mRow + 3, mLine].mUsed || 
                        Game.sExistentBlocks[mRow + 2, mLine + 1].mUsed) {
                        this.HandleCannotMoveDown();
                        return false;
                    }
                    break;
            }

            return base.MoveDown();
        }

        /**
         * 左移。
         */
        public override void MoveLeft() {
            switch (mShape) {
                case Shape.ONE:
                    if (mLine == 0) {
                        return;
                    }
                    if (Game.sExistentBlocks[mRow + 1, mLine - 1].mUsed || 
                        Game.sExistentBlocks[mRow + 2, mLine].mUsed) {
                        return;
                    }
                    break;
                case Shape.TWO:
                    if (mLine == 0) {
                        return;
                    }
                    if (Game.sExistentBlocks[mRow, mLine].mUsed || 
                        Game.sExistentBlocks[mRow + 1, mLine - 1].mUsed || 
                        Game.sExistentBlocks[mRow + 2, mLine - 1].mUsed) {
                        return;
                    }
                    break;
            }

            base.MoveLeft();
        }

        /**
         * 右移。
         */
        public override void MoveRight() {
            switch (mShape) {
                case Shape.ONE:
                    if (mLine == 7) {
                        return;
                    }
                    if (Game.sExistentBlocks[mRow + 1, mLine + 2].mUsed || 
                        Game.sExistentBlocks[mRow + 2, mLine + 3].mUsed) {
                        return;
                    }
                    break;
                case Shape.TWO:
                    if (mLine == 8) {
                        return;
                    }
                    if (Game.sExistentBlocks[mRow, mLine + 2].mUsed || 
                        Game.sExistentBlocks[mRow + 1, mLine + 2].mUsed || 
                        Game.sExistentBlocks[mRow + 2, mLine + 1].mUsed) {
                        return;
                    }
                    break;
            }

            base.MoveRight();
        }

        /**
         * 变形。
         */
        public override void Transform() {
            switch (mShape) {
                case Shape.ONE:
                    if (mRow == -1) {
                        return;
                    }
                    if (Game.sExistentBlocks[mRow, mLine + 1].mUsed ||
                        Game.sExistentBlocks[mRow + 2, mLine].mUsed) {
                        return;
                    }
                    this.Erase();
                    mBlocks[2, 1].mUsed = mBlocks[2, 2].mUsed = false;
                    mBlocks[0, 1].mUsed = mBlocks[2, 0].mUsed = true;
                    mShape = Shape.TWO;
                    break;
                case Shape.TWO:
                    if (mLine == 8) {
                        return;
                    }
                    if (Game.sExistentBlocks[mRow + 2, mLine + 1].mUsed ||
                        Game.sExistentBlocks[mRow + 2, mLine + 2].mUsed) {
                        return;
                    }
                    this.Erase();
                    mBlocks[2, 1].mUsed = mBlocks[2, 2].mUsed = true;
                    mBlocks[0, 1].mUsed = mBlocks[2, 0].mUsed = false;
                    mShape = Shape.ONE;
                    break;
            }

            base.Draw();
        }
    }
}
